import axios from "axios";
import {
  Assignment,
  GradingTask,
  Question,
  Submission,
} from "../utils/constant";

const REQUEST_LIST = [
  "/assignment/listAssignment",
  "/question/listQuestion",
  "/assignment/addAssignment",
  "/pairing/pair",
  "/question/addQuestion",
  "/grade/getAssignedTask",
  "/submission/listSubmission",
];

axios.interceptors.request.use((request) => {
  (request.baseURL = "http://localhost:8080"), (request.withCredentials = true);
  return request;
});

axios.interceptors.response.use(
  (response) => {
    if (REQUEST_LIST.includes(response.config.url!)) {
      return response.data;
    }
    return response;
  },
  (error) => {
    return Promise.reject(error);
  }
);

export interface BaseRes {
  code: string;
  msg: string;
}

export interface GetAssignmentsReq {
  moduleId: number;
}

export interface GetAssignmentsRes extends BaseRes {
  data: Assignment[];
}

export const GetAssignments = async (params: GetAssignmentsReq) => {
  return axios.request<GetAssignmentsReq, GetAssignmentsRes>({
    url: "/assignment/listAssignment",
    method: "GET",
    params,
  });
};

export interface CreateAssignmentReq {
  moduleId: number;
  name: string;
  groupsize: number;
  deadline: string;
}

export const CreateAssignment = async (data: CreateAssignmentReq) => {
  return axios.request({
    url: "/assignment/addAssignment",
    method: "POST",
    data,
  });
};

export interface GetQuestionsReq {
  assignmentId: number;
}
export interface GetQuestionsRes extends BaseRes {
  data: Question[];
}

export const GetQuestions = async (params: GetQuestionsReq) => {
  return axios.request<GetQuestionsReq, GetQuestionsRes>({
    url: "/question/listQuestion",
    method: "GET",
    params,
  });
};

export interface CreateQuestionReq {
  assignmentId: number;
  questionText: string;
  description: string;
  criteria: string;
  minMark: number;
  maxMark: number;
  startDate: number;
  endDate: number;
}

export interface CreateQuestionRes extends BaseRes {
  data: Question;
}

export const CreateQuestion = async (data: CreateQuestionReq) => {
  return axios.request<CreateQuestionReq, CreateQuestionRes>({
    url: "/question/addQuestion",
    method: "POST",
    data,
  });
};

export interface PairingReq {
  moduleId: number;
  assignmentId: number;
  pairSize: number;
}

export const Pairing = async (data: PairingReq) => {
  return axios.request({
    url: "/pairing/pair",
    method: "POST",
    data,
  });
};

export const GetPairInfo = async (pairId: number) => {
  return axios.request({
    url: `/pairing/info/${pairId}`,
    method: "GET",
  });
};

export const GetPairList = async (assignmentId: number) => {
  return axios.request({
    url: `/pairing/listPairsByAssignmentId/${assignmentId}`,
    method: "GET",
  });
};

export const UPLOAD_PATH = "http://localhost:8080/submission/upload";

export interface GetGradingTasksRes extends BaseRes {
  data: GradingTask[];
}

export const GetGradingTasks = async () => {
  return axios.request<any, GetGradingTasksRes>({
    url: "/grade/getAssignedTask",
  });
};

export const GetGrades = async (pairId: number) => {
  return axios.request({
    url: `grade/listGradeByPairId/${pairId}`,
    method: "GET",
  });
};

export const GetGradesAsg = async (assignmentId: number) => {
  return axios.request({
    url: `grade/listGradeByStuId/${assignmentId}`,
    method: "GET",
  });
};

export interface CommonDeleteReq {
  ids: number[];
}

export const DeleteAssignment = async (data: CommonDeleteReq) => {
  return axios.request({
    url: "/assignment/deleteAssignment",
    method: "POST",
    data,
  });
};

export const DeleteQuestion = async (data: CommonDeleteReq) => {
  return axios.request({
    url: "/question/deleteQuestion",
    method: "POST",
    data,
  });
};

export const ClearPair = async (data: CommonDeleteReq) => {
  return axios.request({
    url: "/pairing/delete",
    method: "POST",
    data,
  });
};

export interface GetSubmissionListReq {
  assignmentId: number;
}

export interface GetSubmissionListRes extends BaseRes {
  data: Submission;
}

export const GetSubmission = (data: GetSubmissionListReq) => {
  return axios.request<GetSubmissionListReq, GetSubmissionListRes>({
    url: "/submission/listSubmission",
    method: "POST",
    data,
  });
};

export const GetSubmissionPath = async (
  studentId: number,
  assignmentId: number
) => {
  return axios.request({
    url: `/submission/listSubmission/stu/${studentId}/assignment/${assignmentId}`,
  });
};

export interface DeleteSubmissionReq {
  ids: number[];
}

export const DeleteSubmission = (data: DeleteSubmissionReq) => {
  return axios.request<DeleteSubmissionReq, BaseRes>({
    url: "/submission/delete",
    method: "POST",
    data,
  });
};

// get module info to display
export const GetModuleInfo = async (data: number) => {
  return axios.request({
    method: "GET",
    headers: { satoken: window.localStorage.getItem("satoken") },
    url: `module/info/${data}`,
  });
};

// get user role mapping
export const GetUserRoleList = async () => {
  return axios.request({
    url: "/sys_user_role_mapping/list",
    method: "GET",
  });
};

// get user info
export const GetUserInfo = async () => {
  return axios.request({
    url: "/user/list",
    method: "GET",
  });
};

export const AddUserRole = async (userId: number, roleId: number) => {
  return axios.request({
    url: "/sys_user_role_mapping/update",
    method: "POST",
    data: {
      roleid: roleId,
      userId: userId,
    },
  });
};

// get feedback list
export const GetFeedback = async (assignmentId: number) => {
  return axios.request({
    url: `/grade/getFeedback/${assignmentId}`,
  });
};

// update active (1: completed review, 2: review rejected, 3: pending challenge) status
export interface ActiveReq {
  pairId: number;
  reason: string;
}
export const UpdateActive = async (
  activeRequest: ActiveReq,
  assignmentId: number,
  activeCode: number
) => {
  return axios.request({
    url: `/pairing/update`,
    method: "POST",
    data: {
      id: activeRequest.pairId,
      challengeReason: activeRequest.reason,
      assignmentId: assignmentId,
      active: activeCode,
    },
  });
};

export const GetConfig = async (assignmentId: number) => {
  try {
    const response = await axios.request({
      url: `/grade_calculation_config/${assignmentId}`,
      method: "GET",
    });

    return response.data;
  } catch (error) {
    console.error("Error fetching configuration: ", error);
    throw error;
  }
};

interface GradeCalculationConfig {
  assignmentId?: number | undefined;
  includeParticipation?: number | undefined; // 0 or 1
  ptcWeight?: number | null | undefined;
  includeOutliers?: number | undefined; // 0 or 1
  includeHighest?: number | undefined; // 0 or 1
  includeLowest?: number | undefined; // 0 or 1
}

export const UpdateConfig = async (data: GradeCalculationConfig | null) => {
  try {
    const response = await axios.request({
      url: "/grade_calculation_config/add_or_update",
      method: "POST",
      data,
    });

    return response.data;
  } catch (error) {
    console.error("Error updating configuration: ", error);
    throw error;
  }
};
